﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows;
using System.Runtime.InteropServices.ComTypes;

namespace CustomControls.DatePickerCtr
{
    /// <summary>
    /// 日期+时间
    /// </summary>
    public class ZDatePicker : Control
    {
        #region Private属性

        #region 控件内部元素
        private Popup PART_Popup_New;
        private Popup PART_Popup_TimeSelector;
        /// <summary>
        /// 日历：单个日历
        /// </summary>
        public ZCalendar PART_Calendar;
        /// <summary>
        /// 日历：双日期模式下的第二个日历
        /// </summary>
        private ZCalendar PART_Calendar_Second;
        /// <summary>
        /// 时间选择器
        /// </summary>
        private TimeSelector PART_TimeSelector { set; get; }

        private TimeSelector PART_TimeSelector_Right { set; get; }

        private Grid first_grid { set; get; }
        /// <summary>
        /// 文本框：显示选中的日期
        /// </summary>
        private TextBox PART_TextBox_New { set; get; }
        private TextBlock Left_TimeSelectText { set; get; }
        private TextBlock Right_TimeSelectText { set; get; }
        /// <summary>
        /// 快捷菜单：今天
        /// </summary>
        private Button PART_Btn_Today;
        /// <summary>
        /// 快捷菜单：昨天
        /// </summary>
        private Button PART_Btn_Yestday;
        /// <summary>
        /// 快捷菜单：一周前
        /// </summary>
        private Button PART_Btn_AWeekAgo;
        /// <summary>
        /// 快捷菜单：最近一周
        /// </summary>
        private Button PART_Btn_RecentlyAWeek;
        /// <summary>
        /// 快捷菜单：最近一个月
        /// </summary>
        private Button PART_Btn_RecentlyAMonth;
        /// <summary>
        /// 快捷菜单：最近三个月
        /// </summary>
        private Button PART_Btn_RecentlyThreeMonth;
        /// <summary>
        /// 按钮：清除所选日期
        /// </summary>
        private Button PART_ClearDate;
        /// <summary>
        /// 按钮：确认选择所选日期
        /// </summary>
        private Button PART_ConfirmSelected;
        #endregion

        #endregion

        #region MyRegion

        public string TextInternal
        {
            get { return (string)GetValue(TextInternalProperty); }
            private set { SetValue(TextInternalProperty, value); }
        }

        public static readonly DependencyProperty TextInternalProperty =
            DependencyProperty.Register("TextInternal", typeof(string), typeof(ZDatePicker), new PropertyMetadata(string.Empty));


        #endregion

        #region 依赖属性set get

        #region Type 日历类型
        /// <summary>
        /// 日历类型。SingleDate：单个日期，SingleDateRange：连续的多个日期
        /// </summary>
        public EnumDatePickerType Type
        {
            get { return (EnumDatePickerType)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }

        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(EnumDatePickerType), typeof(ZDatePicker), new PropertyMetadata(EnumDatePickerType.SingleDate, TypeChangedCallback));

        private static void TypeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ZDatePicker datePicker = d as ZDatePicker;
            datePicker.SetSelectionMode(datePicker, (EnumDatePickerType)e.NewValue);
        }
        #endregion

        #region IsShowShortCuts 是否显示快捷操作菜单
        /// <summary>
        /// 是否显示快捷操作菜单
        /// </summary>
        public bool IsShowShortCuts
        {
            get { return (bool)GetValue(IsShowShortCutsProperty); }
            set { SetValue(IsShowShortCutsProperty, value); }
        }

        public static readonly DependencyProperty IsShowShortCutsProperty =
            DependencyProperty.Register("IsShowShortCuts", typeof(bool), typeof(ZDatePicker), new PropertyMetadata(false));
        #endregion

        #region SelectedDate


        public bool IsRestDefaultTime
        {
            get { return (bool)GetValue(IsRestDefaultTimeProperty); }
            set { SetValue(IsRestDefaultTimeProperty, value); }
        }

        public static readonly DependencyProperty IsRestDefaultTimeProperty =
            DependencyProperty.Register("IsRestDefaultTime", typeof(bool), typeof(ZDatePicker), new PropertyMetadata(false, RestDefaultTimeCallBack));

        private static void RestDefaultTimeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (Convert.ToBoolean(e.NewValue)) 
            {
                ZDatePicker datePicker = d as ZDatePicker;
                datePicker.SetDefaultTime();
            }
        }

        public string SelectedRangDate
        {
            get { return (string)GetValue(SelectedRangDateProperty); }
            set { SetValue(SelectedRangDateProperty, value); }
        }

        public static readonly DependencyProperty SelectedRangDateProperty =
            DependencyProperty.Register("SelectedRangDate", typeof(string), typeof(ZDatePicker),new PropertyMetadata("", SelectedRangDateCallBack));

        private static void SelectedRangDateCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            return;
            Console.WriteLine(e.NewValue);
            try
            {
                ZDatePicker datePicker = d as ZDatePicker;
                if (datePicker.Type == EnumDatePickerType.SingleDateRange) 
                {
                    if (!string.IsNullOrEmpty(e.NewValue.ToString()))
                    {
                        string[] str = e.NewValue.ToString().Split('~');
                        if (datePicker.Right_TimeSelectText != null && datePicker.Left_TimeSelectText != null && datePicker.PART_TextBox_New != null)
                        {
                            datePicker.Left_TimeSelectText.Text = str[0];
                            datePicker.Right_TimeSelectText.Text = str[1];
                            datePicker.SelectedDateStart = Convert.ToDateTime(str[0]);
                            datePicker.SelectedDateEnd = Convert.ToDateTime(str[1]);
                            datePicker.PART_TextBox_New.Text = datePicker.Left_TimeSelectText.Text + "~" + datePicker.Right_TimeSelectText.Text;

                            datePicker.SelectedRangDate = datePicker.Left_TimeSelectText.Text + "~" + datePicker.Right_TimeSelectText.Text;
                        }

                    }
                }
                 
               
            }
            catch (Exception ex) 
            {
            
            }

        }

        /// <summary>
        /// 获取或设置选中的日期
        /// </summary>
        public DateTime? SelectedDate
        {
            get { return (DateTime?)GetValue(SelectedDateProperty); }
            set { SetValue(SelectedDateProperty, value); }
        }

        public static readonly DependencyProperty SelectedDateProperty =
            DependencyProperty.Register("SelectedDate", typeof(DateTime?), typeof(ZDatePicker), new PropertyMetadata(null, SelectedDateCallback, SelectedDateCoerceValueCallback));

        private static void SelectedDateCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ZDatePicker datePicker = d as ZDatePicker;
            DateTime? dateTime = (DateTime?)e.NewValue;
            if (dateTime.HasValue)
            {
                DateTime dt = dateTime.Value;
                if (datePicker.SelectedTime == null)
                {
                    datePicker.SelectedTime = dt;
                }

                datePicker.SetSingleDateToTextBox(dt);
            }
            else
            {
                //TODO
                //显示水印
            }
        }

        private static object SelectedDateCoerceValueCallback(DependencyObject d, object value)
        {
            ZDatePicker datePicker = d as ZDatePicker;

            DateTime? dateTime = (DateTime?)value;
            if (datePicker.PART_Calendar != null)
            {
                datePicker.PART_Calendar.SelectedDate = dateTime;
            }
            return dateTime;
        }

        #endregion

        #region SelectedDates
        public ObservableCollection<DateTime> SelectedDates
        {
            get { return (ObservableCollection<DateTime>)GetValue(SelectedDatesProperty); }
            set { SetValue(SelectedDatesProperty, value); }
        }

        public static readonly DependencyProperty SelectedDatesProperty =
            DependencyProperty.Register("SelectedDates", typeof(ObservableCollection<DateTime>), typeof(ZDatePicker), new PropertyMetadata(null, SelectedDateChangedCallback));

        private static void SelectedDateChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ZDatePicker datePicker = d as ZDatePicker;

            foreach (DateTime date in datePicker.SelectedDates)
            {
                if (date.Year == datePicker.PART_Calendar.DisplayDate.Year
                    && date.Month == datePicker.PART_Calendar.DisplayDate.Month)
                {
                    datePicker.PART_Calendar.SelectedDates.Add(date);
                }
                else
                {
                    datePicker.PART_Calendar_Second.SelectedDates.Add(date);
                }
            }
        }
        #endregion

        #region SelectedDateStart

        public DateTime? SelectedDateStart
        {
            get { return (DateTime?)GetValue(SelectedDateStartProperty); }
            set { SetValue(SelectedDateStartProperty, value); }
        }

        public static readonly DependencyProperty SelectedDateStartProperty =
            DependencyProperty.Register("SelectedDateStart", typeof(DateTime?), typeof(ZDatePicker), new PropertyMetadata(null));

        #endregion

        #region SelectedDateEnd

        public DateTime? SelectedDateEnd
        {
            get { return (DateTime?)GetValue(SelectedDateEndProperty); }
            set { SetValue(SelectedDateEndProperty, value); }
        }

        public static readonly DependencyProperty SelectedDateEndProperty =
            DependencyProperty.Register("SelectedDateEnd", typeof(DateTime?), typeof(ZDatePicker), new PropertyMetadata(null, SelectedDateEndCallback, CoerceSelectedDateEnd));

        private static object CoerceSelectedDateEnd(DependencyObject d, object value)
        {
            ZDatePicker datePicker = d as ZDatePicker;
            DateTime? dateTime = (DateTime?)value;
            if (datePicker.PART_Calendar != null)
            {
                datePicker.PART_Calendar.SelectedDate = dateTime;
            }
            if (datePicker.Type== EnumDatePickerType.SingleDateRange) 
            {
                if (!string.IsNullOrEmpty(datePicker.SelectedRangDate))
                {
                    string[] strArray = datePicker.SelectedRangDate.Split('~');
                    var itemLeftTime = Convert.ToDateTime(strArray[0]);

                    var itemRightTime= Convert.ToDateTime(strArray[1]);

                    datePicker.PART_Calendar.SelectedDate = new DateTime(datePicker.PART_Calendar.SelectedDate.Value.Year, datePicker.PART_Calendar.SelectedDate.Value.Month, datePicker.PART_Calendar.SelectedDate.Value.Day, itemRightTime.Hour, itemRightTime.Minute, itemRightTime.Second);

                    datePicker.SelectedDateStart = new DateTime(datePicker.SelectedDateStart.Value.Year, datePicker.SelectedDateStart.Value.Month, datePicker.SelectedDateStart.Value.Day, itemLeftTime.Hour, itemLeftTime.Minute, itemLeftTime.Second);

                }
            }
           

            datePicker.SetSelectedDates(datePicker.SelectedDateStart, datePicker.SelectedDateEnd);
            //datePicker.SetSelectedDates(datePicker.SelectedDateStart, dateTime);
            return dateTime;
        }

        private static void SelectedDateEndCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        #endregion

        #region SelectedTime
        /// <summary>
        /// 获取或设置选中的时间
        /// </summary>
        public DateTime? SelectedTime
        {
            get { return (DateTime?)GetValue(SelectedTimeProperty); }
            set { SetValue(SelectedTimeProperty, value); }
        }


        public static readonly DependencyProperty SelectedTimeProperty =
            DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(ZDatePicker), new PropertyMetadata(null, SelectedTimeChangedCallback));

        public DateTime? SelectedTime_Right
        {
            get { return (DateTime?)GetValue(SelectedTime_RightProperty); }
            set { SetValue(SelectedTime_RightProperty, value); }
        }

        public static readonly DependencyProperty SelectedTime_RightProperty =
         DependencyProperty.Register("SelectedTime_Right", typeof(DateTime?), typeof(ZDatePicker), new PropertyMetadata(null, SelectedTimeChangedCallback));


        private static void SelectedTimeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ZDatePicker datePicker = d as ZDatePicker;
            if (datePicker.Type == EnumDatePickerType.DateTime)
            {
                datePicker.SetSingleDateToTextBox(Convert.ToDateTime(e.NewValue));
            }
            else 
            {
                datePicker.SetSingleDateToTextBox(datePicker.SelectedDate);
            }
            
        }

        #endregion

        #region DisplayDate

        public DateTime DisplayDate
        {
            get { return (DateTime)GetValue(DisplayDateProperty); }
            set { SetValue(DisplayDateProperty, value); }
        }

        public static readonly DependencyProperty DisplayDateProperty =
            DependencyProperty.Register("DisplayDate", typeof(DateTime), typeof(ZDatePicker));

        #endregion

        #region DateStringFormat

        public string DateStringFormat
        {
            get { return (string)GetValue(DateStringFormatProperty); }
            set { SetValue(DateStringFormatProperty, value); }
        }

        public static readonly DependencyProperty DateStringFormatProperty =
            DependencyProperty.Register("DateStringFormat", typeof(string), typeof(ZDatePicker), new PropertyMetadata("yyyy-MM-dd"));

        #endregion

        #region TimeStringFormat

        public string TimeStringFormat
        {
            get { return (string)GetValue(TimeStringFormatProperty); }
            set { SetValue(TimeStringFormatProperty, value); }
        }

        public static readonly DependencyProperty TimeStringFormatProperty =
            DependencyProperty.Register("TimeStringFormat", typeof(string), typeof(ZDatePicker), new PropertyMetadata("HH:mm:ss"));

        #endregion

        #region CornerRadius

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ZDatePicker));

        #endregion

        #region IsShowConfirm
        /// <summary>
        /// 获取或设置是否显示确认按钮
        /// </summary>
        public bool IsShowConfirm
        {
            get { return (bool)GetValue(IsShowConfirmProperty); }
            set { SetValue(IsShowConfirmProperty, value); }
        }

        public static readonly DependencyProperty IsShowConfirmProperty =
            DependencyProperty.Register("IsShowConfirm", typeof(bool), typeof(ZDatePicker), new PropertyMetadata(false));

        #endregion

        #region IsDropDownOpen

        public bool IsDropDownOpen
        {
            get { return (bool)GetValue(IsDropDownOpenProperty); }
            set { SetValue(IsDropDownOpenProperty, value); }
        }

        public static readonly DependencyProperty IsDropDownOpenProperty =
            DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(ZDatePicker), new PropertyMetadata(false));

        #endregion

        #endregion

        #region 内部依赖属性
        public DateTime? SelectedDateInternal
        {
            get { return (DateTime?)GetValue(SelectedDateInternalProperty); }
            set { SetValue(SelectedDateInternalProperty, value); }
        }

        public static readonly DependencyProperty SelectedDateInternalProperty =
            DependencyProperty.Register("SelectedDateInternal", typeof(DateTime?), typeof(ZDatePicker));


        public DateTime DisplayDateInternal
        {
            get { return (DateTime)GetValue(DisplayDateInternalProperty); }
            set { SetValue(DisplayDateInternalProperty, value); }
        }

        public static readonly DependencyProperty DisplayDateInternalProperty =
            DependencyProperty.Register("DisplayDateInternal", typeof(DateTime), typeof(ZDatePicker));


        #endregion

        #region Constructors
        static ZDatePicker()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ZDatePicker), new FrameworkPropertyMetadata(typeof(ZDatePicker)));
        }

        public ZDatePicker()
        {
            this.SelectedDates = new ObservableCollection<DateTime>();
        }
        #endregion

        #region Override方法
        
        public override void OnApplyTemplate()
        {
            if (this.PART_Calendar != null)
            {
                this.PART_Calendar.Owner = null;
            }
            if (this.PART_Calendar_Second != null)
            {
                this.PART_Calendar_Second.Owner = null;
            }
        

            base.OnApplyTemplate();
            this.first_grid= GetTemplateChild("first_grid") as Grid;
         
            this.PART_Popup_New = GetTemplateChild("PART_Popup_New") as Popup;
            this.PART_Popup_TimeSelector = GetTemplateChild("PART_Popup_TimeSelector") as Popup;
            this.PART_Calendar = GetTemplateChild("PART_Calendar") as ZCalendar;
            this.PART_Calendar_Second = GetTemplateChild("PART_Calendar_Second") as ZCalendar;
            this.PART_TimeSelector = GetTemplateChild("PART_TimeSelector") as TimeSelector;
            this.PART_TimeSelector_Right = GetTemplateChild("PART_TimeSelector_Right") as TimeSelector;
            this.PART_TextBox_New = GetTemplateChild("PART_TextBox_New") as TextBox;
            this.Left_TimeSelectText= GetTemplateChild("Left_TimeSelectText") as TextBlock;
            this.Right_TimeSelectText = GetTemplateChild("Right_TimeSelectText") as TextBlock;
            this.PART_Btn_Today = GetTemplateChild("PART_Btn_Today") as Button;
            this.PART_Btn_Yestday = GetTemplateChild("PART_Btn_Yestday") as Button;
            this.PART_Btn_AWeekAgo = GetTemplateChild("PART_Btn_AWeekAgo") as Button;
            this.PART_Btn_RecentlyAWeek = GetTemplateChild("PART_Btn_RecentlyAWeek") as Button;
            this.PART_Btn_RecentlyAMonth = GetTemplateChild("PART_Btn_RecentlyAMonth") as Button;
            this.PART_Btn_RecentlyThreeMonth = GetTemplateChild("PART_Btn_RecentlyThreeMonth") as Button;
            this.PART_ConfirmSelected = GetTemplateChild("PART_ConfirmSelected") as Button;
            this.PART_ClearDate = GetTemplateChild("PART_ClearDate") as Button;

            if (this.PART_Popup_New != null)
            {
                this.PART_Popup_New.Opened += PART_Popup_New_Opened;
                this.PART_Popup_New.Closed += PART_Popup_New_Closed;
            }

            if (this.PART_Popup_TimeSelector != null)
            {
                this.PART_Popup_TimeSelector.Opened += PART_Popup_TimeSelector_Opened;
            }

            if (this.PART_Calendar != null)
            {
                this.PART_Calendar.Owner = this;
                this.PART_Calendar.DateClick += PART_Calendar_DateClick;
                this.PART_Calendar.DisplayDateChanged += PART_Calendar_DisplayDateChanged;
                if (this.Type == EnumDatePickerType.SingleDateRange)
                {
                    this.PART_Calendar.DisplayDate = new DateTime(this.DisplayDate.Year, this.DisplayDate.Month, 1);
                }
            }

            if (this.PART_Calendar_Second != null)
            {
                this.PART_Calendar_Second.Owner = this;
                this.PART_Calendar_Second.DisplayMode = CalendarMode.Month;
                this.PART_Calendar_Second.DisplayDate = this.PART_Calendar.DisplayDate.AddMonths(1);

                this.PART_Calendar_Second.DisplayDateChanged += PART_Calendar_Second_DisplayDateChanged;
                this.PART_Calendar_Second.DateClick += PART_Calendar_Second_DateClick;
            }

            if (this.PART_TimeSelector != null)
            {
                this.PART_TimeSelector.SelectedTimeChanged += PART_TimeSelector_SelectedTimeChanged;
            }

            if (this.PART_TimeSelector_Right != null)
            {
                this.PART_TimeSelector_Right.SelectedTimeChanged += PART_TimeSelector_Right_SelectedTimeChanged;
            }

            if (this.PART_Btn_Today == null)
            {
                this.PART_Btn_Today.Click -= this.PART_Btn_Today_Click;
            }
            if (this.PART_Btn_Yestday == null)
            {
                this.PART_Btn_Yestday.Click -= this.PART_Btn_Yestday_Click;
            }
            if (this.PART_Btn_AWeekAgo == null)
            {
                this.PART_Btn_AWeekAgo.Click -= PART_Btn_AnWeekAgo_Click;
            }

            if (this.PART_Btn_Today != null)
            {
                this.PART_Btn_Today.Click += PART_Btn_Today_Click;
            }
            if (this.PART_Btn_Yestday != null)
            {
                this.PART_Btn_Yestday.Click += PART_Btn_Yestday_Click;
            }
            if (this.PART_Btn_AWeekAgo != null)
            {
                this.PART_Btn_AWeekAgo.Click += PART_Btn_AnWeekAgo_Click;
            }
            if (this.PART_Btn_RecentlyAWeek != null)
            {
                this.PART_Btn_RecentlyAWeek.Click += PART_Btn_RecentlyAWeek_Click; ;
            }
            if (this.PART_Btn_RecentlyAMonth != null)
            {
                this.PART_Btn_RecentlyAMonth.Click += PART_Btn_RecentlyAMonth_Click; ;
            }
            if (this.PART_Btn_RecentlyThreeMonth != null)
            {
                this.PART_Btn_RecentlyThreeMonth.Click += PART_Btn_RecentlyThreeMonth_Click; ;
            }

            if (this.PART_ConfirmSelected != null)
            {
                this.PART_ConfirmSelected.Click += (o, e) => { this.IsDropDownOpen = false; };
            }

            if (this.PART_ClearDate != null)
            {
                this.PART_ClearDate.Click += PART_ClearDate_Click;
            }

            if (this.SelectedDate.HasValue)
            {
                this.SetSingleDateToTextBox(this.SelectedDate);
                this.SetSelectedDate();
            }

            if (this.SelectedDateStart.HasValue && this.SelectedDateEnd.HasValue)
            {
                this.SetRangeDateToTextBox(this.SelectedDateStart, this.SelectedDateEnd);
                this.SetSelectedDates(this.SelectedDateStart, this.SelectedDateEnd);
            }
            if (this.Type == EnumDatePickerType.SingleDateRange)
            {
                SetDefaultTime();
            }
          
            this.SetSelectionMode(this, this.Type);
            this.SetIsShowConfirm();
        }


        private void SetDefaultTime()
        {
            var itemCD = DateTime.Now;
    
            string _StartTime = itemCD.AddHours(-1).ToString("yyyy-MM-dd HH:mm:ss");
            string _EndTime = itemCD.ToString("yyyy-MM-dd HH:mm:ss");
           
            this.SelectedDateStart = Convert.ToDateTime(_StartTime);
            this.SelectedDateEnd = Convert.ToDateTime(_EndTime);
            this.Left_TimeSelectText.Text = _StartTime;
            this.Right_TimeSelectText.Text = _EndTime;
            this.PART_TextBox_New.Text = this.Left_TimeSelectText.Text + "~" + this.Right_TimeSelectText.Text;
            this.SelectedRangDate = this.Left_TimeSelectText.Text + "~" + this.Right_TimeSelectText.Text;
        }

        private void PART_Popup_TimeSelector_Opened(object sender, EventArgs e)
        {

            if (this.PART_TimeSelector != null)
            {
                this.PART_TimeSelector.SetButtonSelected();
            }
            if (this.PART_TimeSelector_Right != null)
            {
                this.PART_TimeSelector_Right.SetButtonSelected();
            }
        }

        private void PART_TimeSelector_SelectedTimeChanged(object sender, RoutedPropertyChangedEventArgs<DateTime?> e)
        {
            if (e.NewValue.HasValue)
            {
                this.SelectedTime = e.NewValue;
            }
        }

        private void PART_TimeSelector_Right_SelectedTimeChanged(object sender, RoutedPropertyChangedEventArgs<DateTime?> e)
        {
            if (e.NewValue.HasValue)
            {
                this.SelectedTime_Right = e.NewValue;
            }
        }
        #endregion

        #region Private方法

        private void SetSelectedDate()
        {
            if (this.PART_Calendar != null)
            {
                this.PART_Calendar.SelectedDate = this.SelectedDate;
            }
        }

        private void PART_ClearDate_Click(object sender, RoutedEventArgs e)
        {
            if (this.PART_TextBox_New != null)
            {
                this.PART_TextBox_New.Text = string.Empty;
            }
            this.ClearSelectedDates();
        }

        /// <summary>
        /// 日期点击处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Calendar_DateClick(object sender, RoutedPropertyChangedEventArgs<DateTime?> e)
        {
            if (this.PART_Calendar.DisplayMode == CalendarMode.Month)
            {
                ZCalendar calendar = sender as ZCalendar;
                if (calendar == null)
                {
                    return;
                }
                if (calendar.SelectedDate == null)
                {
                    return;
                }
                switch (this.Type)
                {
                    case EnumDatePickerType.SingleDate:
                    case EnumDatePickerType.DateTime:
                        this.SetSelectedDate(calendar.SelectedDate.Value);
                        break;
                    case EnumDatePickerType.SingleDateRange:
                        DateTime? dateTime = calendar.SelectedDate;
                        this.SelectedDateStart = dateTime;
                        calendar.SelectedDate = dateTime;
                        string _str = DateTime.Now.ToString("yyyy-MM-dd 23:59:59");
                        this.SelectedDateEnd = this.SelectedDateEnd == null ? Convert.ToDateTime(_str) : this.SelectedDateEnd;
                                            
                        this.HandleSingleDateRange(calendar);
                        break;
                }
            }
        }

        /// <summary>
        /// 双日历模式下的第二个日历的日期点击处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Calendar_Second_DateClick(object sender, RoutedPropertyChangedEventArgs<DateTime?> e)
        {
            if (this.PART_Calendar_Second.SelectedDate == null)
            {
                return;
            }

            if (sender is ZCalendar)
            {
                if (this.PART_Calendar_Second.DisplayMode == CalendarMode.Month)
                {
                    ZCalendar calendar = sender as ZCalendar;
                    if (calendar == null)
                    {
                        return;
                    }
                    if (calendar.SelectedDate == null)
                    {
                        return;
                    }
                    switch (this.Type)
                    {
                        case EnumDatePickerType.SingleDateRange:
                            DateTime? dateTime = calendar.SelectedDate;
                            this.SelectedDateEnd = new DateTime(dateTime.Value.Year,dateTime.Value.Month,dateTime.Value.Day, this.SelectedDateEnd.Value.Hour, this.SelectedDateEnd.Value.Minute, this.SelectedDateEnd.Value.Second);
                            calendar.SelectedDate = dateTime;
                            this.HandleSingleDateRange(calendar);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// 日期连选
        /// </summary>
        /// <param name="calendar"></param>
        private void HandleSingleDateRange(ZCalendar calendar)
        {
            if (this.Type==EnumDatePickerType.SingleDateRange)
            {
                this.SetSelectedDates(this.SelectedDateStart, this.SelectedDateEnd);

                this.SetRangeDateToTextBox(this.SelectedDateStart, this.SelectedDateEnd);
                return;
            }
            DateTime? dateTime = calendar.SelectedDate;
         
            if (this.SelectedDateStart != null && this.SelectedDateEnd != null)
            {
                this.SelectedDates.Clear();
                this.PART_Calendar.SelectedDates.Clear();
                this.PART_Calendar_Second.SelectedDates.Clear();
                this.SelectedDateStart = null;
                this.SelectedDateEnd = null;
                this.PART_Calendar.SelectedDate = null;
                this.PART_Calendar_Second.SelectedDate = null;
            }

            if (this.SelectedDateStart == null)
            {
                this.SelectedDateStart = dateTime;
                calendar.SelectedDate = dateTime;
            }
            else if (calendar.SelectedDate < this.SelectedDateStart)
            {
                this.SelectedDates.Clear();
                this.PART_Calendar.SelectedDates.Clear();
                this.PART_Calendar_Second.SelectedDates.Clear();
                this.SelectedDateStart = dateTime;
                this.PART_Calendar.SelectedDate = null;
                this.PART_Calendar_Second.SelectedDate = null;
                calendar.SelectedDate = dateTime;
            }
            else
            {
                
                this.SetSelectedDates(this.SelectedDateStart, this.SelectedDateEnd);

                this.SetRangeDateToTextBox(this.SelectedDateStart, this.SelectedDateEnd);
            }
        }

        private void HandleSelectedDatesChanged()
        {
            ZDatePicker datePicker = this;
            if (datePicker.PART_Calendar == null || datePicker.PART_Calendar_Second == null)
            {
                return;
            }

            datePicker.PART_Calendar.SelectedDates.Clear();
            datePicker.PART_Calendar_Second.SelectedDates.Clear();

            ObservableCollection<DateTime> dt1 = new ObservableCollection<DateTime>();
            ObservableCollection<DateTime> dt2 = new ObservableCollection<DateTime>();

            foreach (DateTime date in datePicker.SelectedDates)
            {
                //选中的日期段可能会跨越好几个月，因此先找出属于第一个日历的日期，然后剩余的日期都显示在第二个日历上面
                if (DateTimeHelpClass.MonthIsEqual(date, this.PART_Calendar.DisplayDate))
                {
                    dt1.Add(date);
                }
                else
                {
                    dt2.Add(date);
                }
            }

            datePicker.PART_Calendar.SelectedDates = dt1;
            datePicker.PART_Calendar_Second.SelectedDates = dt2;
        }

        private void PART_Popup_New_Opened(object sender, EventArgs e)
        {
            if (this.PART_Calendar == null)
            {
                return;
            }

            this.PART_Calendar.DisplayMode = CalendarMode.Month;

            switch (this.Type)
            {
                case EnumDatePickerType.SingleDate:
                    break;
                case EnumDatePickerType.SingleDateRange:
                    this.PART_Calendar_Second.DisplayMode = CalendarMode.Month;
                    break;
                default:
                    break;
            }
        }

        private void PART_Popup_New_Closed(object sender, EventArgs e)
        {
            //if (Type == EnumDatePickerType.DateTime)
            //{
            //    this.SelectedRangDate = this.Left_TimeSelectText.Text;
            //}
            //else 
            {
                this.SelectedRangDate = this.PART_TextBox_New.Text;
            }
            
            
        }
        #region 双日历模式下联动日期

        private void PART_Calendar_DisplayDateChanged(object sender, RoutedPropertyChangedEventArgs<DateTime> e)
        {
            if (e.NewValue == null)
            {
                return;
            }
            if (e.NewValue == null)
            {
                return;
            }

            if (this.Type == EnumDatePickerType.SingleDateRange)
            {
                this.PART_Calendar_Second.DisplayDate = e.NewValue.AddMonths(1);
            }
        }

        private void PART_Calendar_Second_DisplayDateChanged(object sender, RoutedPropertyChangedEventArgs<DateTime> e)
        {
            if (this.PART_Calendar == null)
            {
                return;
            }
            if (e.NewValue == null)
            {
                return;
            }
            if (e.NewValue == null)
            {
                return;
            }

            if (this.Type == EnumDatePickerType.SingleDateRange)
            {
                this.PART_Calendar.DisplayDate = e.NewValue.AddMonths(-1);
            }
        }
        #endregion

        #region 快捷菜单点击事件
        /// <summary>
        /// 点击了“今天”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_Today_Click(object sender, RoutedEventArgs e)
        {
            this.SetSelectedDate(DateTime.Today);
        }

        /// <summary>
        /// 点击了“昨天”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_Yestday_Click(object sender, RoutedEventArgs e)
        {
            this.SetSelectedDate(DateTime.Today.AddDays(-1));
        }

        /// <summary>
        /// 点击了“一周前”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_AnWeekAgo_Click(object sender, RoutedEventArgs e)
        {
            this.SelectedDates.Clear();
            this.PART_Calendar.SelectedDates.Clear();
            this.PART_Calendar_Second.SelectedDates.Clear();
            this.SelectedDateStart = null;
            this.SelectedDateEnd = null;
            this.PART_Calendar.SelectedDate = null;
            this.PART_Calendar_Second.SelectedDate = null;
            this.SetSelectedDate(DateTime.Today.AddDays(-7));
        }

        /// <summary>
        /// 点击了“最近一周”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_RecentlyAWeek_Click(object sender, RoutedEventArgs e)
        {
            this.ClearSelectedDates();
            this.FastSetSelectedDates(DateTime.Today.AddDays(-7), DateTime.Today);
        }

        /// <summary>
        /// 点击了“最近一个月”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_RecentlyAMonth_Click(object sender, RoutedEventArgs e)
        {
            this.ClearSelectedDates();
            this.FastSetSelectedDates(DateTime.Today.AddMonths(-1), DateTime.Today);
        }

        /// <summary>
        /// 点击了“最近三个月”快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PART_Btn_RecentlyThreeMonth_Click(object sender, RoutedEventArgs e)
        {
            this.ClearSelectedDates();
            this.FastSetSelectedDates(DateTime.Today.AddMonths(-3), DateTime.Today);
        }
        #endregion

        private void FastSetSelectedDates(DateTime? startDate, DateTime? endDate)
        {
            if (this.PART_Calendar == null || this.PART_Calendar_Second == null)
            {
                return;
            }

            this.SelectedDateStart = startDate;
            this.SelectedDateEnd = endDate;
            this.PART_Calendar_Second.SelectedDate = null;
            this.PART_Calendar.SelectedDate = null;

            this.PART_Calendar.DisplayDate = new DateTime(startDate.Value.Date.Year, startDate.Value.Date.Month, 1);
            this.PART_Calendar_Second.DisplayDate = new DateTime(endDate.Value.Date.Year, endDate.Value.Date.Month, 1);

            this.SetSelectedDates(this.SelectedDateStart, this.SelectedDateEnd);
        }

        /// <summary>
        /// 根据起始日期与结束日期，计算总共的选中日期
        /// </summary>
        /// <param name="selectedDateStart"></param>
        /// <param name="selectedDateEnd"></param>
        private void SetSelectedDates(DateTime? selectedDateStart, DateTime? selectedDateEnd)
        {
            this.SelectedDates.Clear();
            DateTime? dtTemp = selectedDateStart;
            while (dtTemp <= selectedDateEnd)
            {
                this.SelectedDates.Add(dtTemp.Value);
                dtTemp = dtTemp.Value.AddDays(1);
            }
            this.HandleSelectedDatesChanged();

            if (this.PART_TextBox_New != null && selectedDateStart.HasValue && selectedDateEnd.HasValue)
            {
                this.SetRangeDateToTextBox(selectedDateStart, selectedDateEnd);
            }
        }

        /// <summary>
        /// 设置选中的日期
        /// </summary>
        /// <param name="dateTime"></param>
        private void SetSelectedDate(DateTime dateTime)
        {
            this.SelectedDate = dateTime;
            this.DisplayDate = dateTime;
            //if(this.PART_Calendar != null)
            //{
            //    this.PART_Calendar.SelectedDate = dateTime;
            //}
            if (this.Type!= EnumDatePickerType.SingleDateRange&& this.Type != EnumDatePickerType.DateTime) 
            {
                //设置弹出框是否关闭
                this.IsDropDownOpen = this.IsShowConfirm;
            }
            
        }

        /// <summary>
        /// 将当前选择的日期显示到文本框中
        /// </summary>
        /// <param name="selectedDate"></param>
        public void SetSingleDateToTextBox(DateTime? selectedDate)
        {
            if (this.PART_TextBox_New != null)
            {
                if (!selectedDate.HasValue)
                {
                    if (this.Type == EnumDatePickerType.DateTime)
                    {
                        selectedDate = new DateTime(this.SelectedTime.Value.Year, this.SelectedTime.Value.Month, this.SelectedTime.Value.Day, this.SelectedTime.Value.Hour, this.SelectedTime.Value.Minute, this.SelectedTime.Value.Second);
                    }
                    else if (this.Type == EnumDatePickerType.SingleDateRange) 
                    {
                        
                    }
                    else
                    {
                        selectedDate = new DateTime?(DateTime.Today);
                    }

                }
                switch (this.Type)
                {
                    case EnumDatePickerType.SingleDate:
                        this.PART_TextBox_New.Text = selectedDate.Value.ToString(this.DateStringFormat);
                        break;
                    case EnumDatePickerType.DateTime:
                        if (this.SelectedTime.HasValue && this.PART_TimeSelector != null)
                        {
                            var itemT = new DateTime(selectedDate.Value.Year, selectedDate.Value.Month, selectedDate.Value.Day, this.SelectedTime.Value.Hour, this.SelectedTime.Value.Minute, this.SelectedTime.Value.Second);
                            this.SelectedTime = itemT;
                            this.PART_TimeSelector.SelectedTime = this.SelectedTime;
                            this.Left_TimeSelectText.Text=this.PART_TextBox_New.Text = string.Format("{0} {1}"
                                , selectedDate.Value.ToString(this.DateStringFormat)
                                , this.SelectedTime.Value.ToString(this.TimeStringFormat));
                        }
                        break;
                    case EnumDatePickerType.SingleDateRange:
                        if (this.SelectedTime.HasValue) 
                        {
                            this.PART_TimeSelector.SelectedTime = this.SelectedTime;
                            this.Left_TimeSelectText.Text = this.SelectedDateStart.Value.ToString(this.DateStringFormat) + " " + this.SelectedTime.Value.ToString(this.TimeStringFormat);
                        }
                        if (this.SelectedTime_Right.HasValue )
                        {                         
                            this.PART_TimeSelector_Right.SelectedTime = this.SelectedTime_Right;                            
                            this.Right_TimeSelectText.Text = this.SelectedDateEnd.Value.ToString(this.DateStringFormat) + " " + this.SelectedTime_Right.Value.ToString(this.TimeStringFormat);
                        }
                        string itemTime_1 = this.SelectedTime == null ? this.SelectedDateStart.Value.ToString("HH:mm:ss") : this.SelectedTime.Value.ToString(this.TimeStringFormat);
                        string itemTime_2 = this.SelectedTime_Right == null ?Convert.ToDateTime(this.Right_TimeSelectText.Text).ToString("HH:mm:ss") : this.SelectedTime_Right.Value.ToString(this.TimeStringFormat);

                        this.PART_TextBox_New.Text = this.SelectedDateStart.Value.ToString(this.DateStringFormat) + " " + itemTime_1 + " ~ " + this.SelectedDateEnd.Value.ToString(this.DateStringFormat) + " " + itemTime_2;                       
                        break;
                }
                if (selectedDate!=null) 
                {
                    this.SetSelectedDate(selectedDate.Value);
                }     
            }
        }

        /// <summary>
        /// 将当前选择的日期段显示到文本框中
        /// </summary>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        private void SetRangeDateToTextBox(DateTime? startDate, DateTime? endDate)
        {
            if (this.PART_TextBox_New == null)
            {
                return;
            }

            if (startDate.HasValue && endDate.HasValue)
            {
                string Item_str_1 = this.SelectedTime == null ? startDate.Value.ToString("HH:mm:ss") : this.SelectedTime.Value.ToString(this.TimeStringFormat);
                string Item_str_2 = this.SelectedTime_Right == null ? endDate.Value.ToString("HH:mm:ss") : this.SelectedTime_Right.Value.ToString(this.TimeStringFormat);
                this.Left_TimeSelectText.Text = startDate.Value.ToString(this.DateStringFormat)+" "+ Item_str_1;
                this.Right_TimeSelectText.Text = endDate.Value.ToString(this.DateStringFormat) + " " + Item_str_2;
                this.PART_TextBox_New.Text = startDate.Value.ToString(this.DateStringFormat)+" "+ Item_str_1 + " ~ " + endDate.Value.ToString(this.DateStringFormat)+" "+ Item_str_2;
            }
            if (this.Type!= EnumDatePickerType.SingleDateRange)
            {
                //选了两个日期之后，关闭日期选择框
                this.IsDropDownOpen = this.IsShowConfirm;
            }
            
        }

        /// <summary>
        /// 设置控件的类型
        /// </summary>
        /// <param name="datePicker"></param>
        /// <param name="type"></param>
        private void SetSelectionMode(ZDatePicker datePicker, EnumDatePickerType type)
        {
            switch (type)
            {
                case EnumDatePickerType.SingleDate:
                    if (datePicker.PART_Calendar != null)
                    {
                        datePicker.PART_Calendar.SelectionMode = CalendarSelectionMode.SingleDate;
                    }
                    break;
                case EnumDatePickerType.SingleDateRange:
                    if (datePicker.PART_Calendar != null)
                    {
                        datePicker.PART_Calendar.SelectionMode = CalendarSelectionMode.SingleRange;
                    }
                    if (datePicker.PART_Calendar_Second != null)
                    {
                        datePicker.PART_Calendar_Second.SelectionMode = CalendarSelectionMode.SingleRange;
                    }
                    break;
                case EnumDatePickerType.Year:
                    break;
                case EnumDatePickerType.Month:
                    break;
                case EnumDatePickerType.DateTime:
                    break;
                case EnumDatePickerType.DateTimeRange:
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 根据控件类型，设置是否显示确认框
        /// </summary>
        private void SetIsShowConfirm()
        {
            //当控件可以选择时间的时候，默认显示确认框
            switch (this.Type)
            {
                case EnumDatePickerType.DateTime:
                case EnumDatePickerType.DateTimeRange:
                    this.IsShowConfirm = true;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 清除已选择的日期
        /// </summary>
        private void ClearSelectedDates()
        {
            this.SelectedDates.Clear();
            this.SelectedDateStart = null;
            this.SelectedDateEnd = null;

            if (this.PART_Calendar != null)
            {
                this.PART_Calendar.SelectedDate = null;
                this.PART_Calendar.SelectedDates.Clear();
            }
            if (this.PART_Calendar_Second != null)
            {
                this.PART_Calendar_Second.SelectedDate = null;
                this.PART_Calendar_Second.SelectedDates.Clear();
            }
        }
        #endregion
    }

}
